<!-- 此模块是数据权限定制化树结构 父树 -->
<template>
  <div id="qiankun-data-tree" ref="qiankunDataTree">
    <el-tree
      ref="tree"
      :data="tree"
      node-key="route"
      :expand-on-click-node="false"
      :default-expand-all="true"
      :props="defaultProps"
      :indent="30"
    >
      <span class="custom-tree-node clearfix" slot-scope="{ node, data }">
        <span class="fl tree-label">{{ node.label }}</span>
        <div class="qiankun-operation fl">
          <a-radio-group
            v-model="data.dimension"
            :disabled="isDetail"
            @change="($event) => { handleChecked($event, data) }"
          >
            <span class="radio-item"
              v-for="(item, index) in dimensionDict(data.dimensionList)"
              :key="index"
              @click="($event) => { handleChecked($event, data, item.value) }"
            >
              <a-radio :value="item.value">
                {{ item.label }}
              </a-radio>
            </span>
          </a-radio-group>
        </div>
      </span>
    </el-tree>
    <!-- 组织，身份权限子树弹窗 -->
    <a-modal
      :getContainer="() => $refs.qiankunDataTree"
      v-model="subVisible"
      :title="subTreeModalTitle"
      :centered="true"
    >
      <!-- loading区域 -->
      <a-spin class="sub-loading" v-if="subContentLoading" />
      <!-- 子树区域 -->
      <data-permission-sub-tree
        ref="subTree"
        :isLoading="subContentLoading"
        :treeData="subTree"
        :permissionList="permissionList"
        :route="route"
        :dimension="dimension"
        :checkFn="checkFn"
        :checkStrictly="checkStrictly"
        :pageType="pageType"
      />
      <template slot="footer">
        <a-button key="back" @click="handleSubCancel">
          取消
        </a-button>
        <a-button key="submit" type="primary" :loading="subLoading" @click="handleSubOk">
          确定
        </a-button>
      </template>
    </a-modal>
  </div>
</template>
<script>
import cloneDeep from 'lodash.clonedeep'
import { getNewDataPermissionSubTree } from "@/services/roleManage.js";
import { dimensionDict, popDimensionList } from '../config';
import dataPermissionSubTree from "./dataPermissionSubTree.vue";

const dimensionDictObject = cloneDeep(dimensionDict)

export default {
  name: "tree",
  props: {
    treeData: {
      type: Array,
      default: () => []
    },
    // 同步数据
    syncData: {
      type: Function,
      default: () => {}
    },
    // 选中的数据
    checkedKeys: {
      type: Array,
      default: () => []
    },
    treeEmptyText: {
      type: String,
      default: "暂无数据"
    },
    pageType: {
      type: String,
      default: "add"
    },
    roleInfo: {
      type: Object,
      default: () => {}
    }
  },
  components: {
    dataPermissionSubTree
  },
  data() {
    return {
      value: [],
      tree: [],
      defaultProps: {
        children: "children",
        label: "routeName"
      },
      subTree: [],
      subTreeDepartment: [], // 部门子树数据
      subTreeRole: [], // 角色子树数据
      permissionList: [], // 子树选中的ids
      subVisible: false,
      subLoading: false, // 子树弹窗，确定按钮的loading
      subContentLoading: false, // 子树内容的loading
      dimension: '', // 当前选择的维度
      route: '', // 当前选择的路由
      currentRouterTarget: {}, // 当前的路由对象
      subList: [], // 有子树的结构参数列表
      checkStrictly: false
    };
  },
  watch: {
    // 代表着抽屉打开了
    treeData(val) {
      this.tree = cloneDeep(val);
      this.subTreeDepartment = [];
      this.subTreeRole = [];
    },
    // 子树弹窗控制变量
    subVisible(val) {
      val && (this.subConfirmState = false) // 窗口打开设置哨兵变量
      !val && !this.subConfirmState && this.handleSubCancel() // 关闭时如果是取消则回归状态
    }
  },
  mounted() {
    this.tree = cloneDeep(this.treeData);
  },
  computed: {
    isDetail() {
      return this.pageType === "view";
    },
    dimensionDict() {
      return (list) => {
        if (!list) return []
        const result = []
        list.forEach((item) => {
          result.push({ 'label': dimensionDictObject[item], 'value': item })
        })
        return result;
      }
    },
    subTreeModalTitle() {
      let prefix = ''
      this.pageType === "view" && (prefix = '查看')
      this.pageType === "edit" && (prefix = '编辑')
      return prefix + dimensionDictObject[this.dimension]
    }
  },
  methods: {
    async handleChecked(e, data, currentDimension) {
      // 查看的时候
      if (this.isDetail) {
        const viewFlag1 = data.dimension !== currentDimension // 如果选择的不是当前选中的
        const viewFlag2 = !popDimensionList.includes(currentDimension) // 当前不属于弹出的维度
        if (viewFlag1 || viewFlag2) {
          return
        }
      }
      // 1. 挂载当前对象
      this.currentRouterTarget = data;
      const { route, dimension, permissionList } = cloneDeep(data)
      // 2. 判断是否是第一次点击，初始化时会没有被选中，没有维度这个场景需要记录
      if (!data.checkCount) {
        data.checkCount = 1
        data.dimensionServer = dimension || '' // 注意这里可能是 ''
        data.permissionListServer = cloneDeep(permissionList) || []; // 服务端数据备份
      } else {
        data.checkCount ++
      }
      // 3. 编辑状态下的数据同步
      data.dimension = currentDimension // 更新当前维度
      data.dimensionPre = dimension // 记录上一个维度
      if (!popDimensionList.includes(currentDimension) && !this.isDetail) {
        this.currentRouterUpdateHandler(this.subList, { route, dimension: currentDimension })
        return
      }
      this.route = route
      this.dimension = currentDimension
      this.subVisible = true
      this.checkStrictly = currentDimension === 'role'
      const { id, departmentId } = this.roleInfo
      const params = {
        dimension: currentDimension,
        roleId: id,
        departmentId
      }
      this.getSubTree(params, data)
    },
    // 点选组织和身份时候请求子树
    async getSubTree(params, target) {
      // 1. 检测是否需要调接口，如果是第二次则不需要，第一次都会初始化
      if (!this.checkNeedToGetSubTree()) {
        let cachedData = null;
        (this.dimension === 'department') && (cachedData = cloneDeep(this.subTreeDepartment));
        (this.dimension === 'role') && (cachedData = cloneDeep(this.subTreeRole));
        cachedData && (target.subTree = this.subTree = cachedData); // 更新树
        this.setHistoryIds() // 更新历史权限
        return
      }
      // 2. 第一次请求数据
      this.isLoading = true;
      target.subTree = this.subTree = [] // 信息初始化
      this.subContentLoading = true; // loading 初始化
      try {
        // this.isDetail && (params.view = true) // 组件库原因，目前element-ui不支持根节点disabled为true时的checked状态回选
        let { data: { data, code } } = await getNewDataPermissionSubTree(params);
        if (code !== 200) {
          return
        }
        target.subTree = this.subTree = data && [data] || [];
        const { permissionList, dimensionServer } = target;
        this.permissionList = this.dimension === dimensionServer && cloneDeep(permissionList) || [] // 第一次更新挂载当前权限
        // 对数据进行处理
        this.subTreeBackupHandler(data)
      } catch(e) {
        console.log(e)
      } finally {
        this.isLoading = false;
        this.subContentLoading = false;
      }
    },
    // 检测是否需要配置子树数据
    checkNeedToGetSubTree() {
      let flag = true
      // 1. 非初始化条件判断 阻塞
      if (this.dimension === 'department' && this.subTreeDepartment.length) {
        flag = false
      }
      if (this.dimension === 'role' && this.subTreeRole.length) {
        flag = false
      }
      return flag
    },
    // 备份初始化的两棵子树
    subTreeBackupHandler(data) {
      if (!this.checkNeedToGetSubTree()) return
      // 2. 初始化条件判断 配置
      let attr = ''
      switch(this.dimension) {
        case 'department':
          attr = 'subTreeDepartment'
          break;
        case 'role':
          attr = 'subTreeRole'
          break;
        default:
      }
      attr && (this[attr] = cloneDeep([data]))
    },
    // 子树弹窗关闭
    handleSubCancel() {
      this.subVisible = false
      const { route, currentRouterTarget } = this
      const { permissionListServer, dimensionServer } = currentRouterTarget
      const value = permissionListServer // 取消的时候，重置到服务器的数据
      const dimension = dimensionServer
      this.currentRouterUpdateHandler(this.subList, { route, dimension, value })
    },
    // 子树弹窗，点击确定
    handleSubOk() {
      this.subVisible = false;
      this.subConfirmState = true;
    },
    // 查询当前路由是否在列表中，如果不存在，则push, 否则进行更新
    currentRouterUpdateHandler(list, json) {
      const { route, value, dimension } = json
      // 组织和身份
      if (value) {
        this.currentRouterTarget.permissionList = value;
        this.currentRouterTarget.dimension = value?.length ? dimension : '';
      }
      // 企业和用户
      if (!popDimensionList.includes(dimension)) {
        this.currentRouterTarget.permissionList = [];
        this.currentRouterTarget.dimension = dimension;
      }
      const index = list.findIndex((item) => { return item.route === route})
      if (index === -1) {
        list.push(json) // 查询不到，是新数据, 则新增
      } else {
        list[index] = json // 查询到，旧数据，则更新
      }
      this.syncData(list) // 向外同步数据
    },
    // 子树选择时的回调
    checkFn(treeTarget, route, dimension) {
      const value = treeTarget.checkedKeys
      this.currentRouterUpdateHandler(this.subList, { route, dimension, value})
    },
    // 从子树选择的数据中中拆解出之前勾选的数据挂载到当前对象中进行记录
    setHistoryIds() {
      const {currentRouterTarget, subList } = this
      const { route, dimension, dimensionServer, dimensionPre, permissionList, permissionListServer } = currentRouterTarget
      const current = subList.filter((item)=> item.route === route)[0]
      if (!current) {
        this.permissionList = currentRouterTarget.permissionList
        return
      }
      let value = permissionList
      // 不同维度的切换
      if (dimension !== dimensionServer) {
        dimension !== dimensionPre && (value = [])
      } else {
        dimension !== dimensionPre && (value = permissionListServer)
      }
      currentRouterTarget.permissionList = this.permissionList = value
    }
  }
};
</script>
<style lang="less" scoped>
#qiankun-data-tree {
    min-height: 200px;
    &-scroll {
      max-height: 300px;
      overflow-y: auto;
    }
    /deep/ .el-tree-node__content {
      height: auto;
      overflow: hidden;
      display: block;
      .el-tree-node__expand-icon {
        display: none;
      }
    }
    .custom-tree-node {
      display: block;
      font-size: 14px;
      padding-right: 10px;
    }
    .tree-label {
      width: 30%;
      padding-left: 20px;
      line-height: 26px;
    }
    .custom-important {
      color: red;
    }
    .extend {
      padding: 0 8px;
    }
    .custom-sub-tree {
      padding: 10px 0;
    }
    /deep/ .el-tree-node:focus > .el-tree-node__content {
      background: transparent!important;
    }
    /deep/ .el-tree-node__content {
      padding: 5px 0;
      .el-checkbox {
        height: 20px;
      }
    }
    /deep/ .ant-modal {
      width: 800px!important;
      height: 600px!important;
      .ant-modal-body {
        height: 500px;
        overflow: auto;
        position: relative;
      }
    }
    .sub-loading {
      position: absolute;
      left: 50%;
      top: 50%;
      z-index: 9;
    }
}
</style>
